package labs.utilities;

import static labs.utilities.PrintUtilities.printError;
import static labs.utilities.PrintUtilities.printException;
import static labs.utilities.PrintUtilities.printInfo;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;

public class LabsFileWriter extends LabsFileIO {
	private BufferedWriter writer;
	private final char openAction;

	public LabsFileWriter(String fileName) {
		this(fileName, true, 'n');

	}

	public LabsFileWriter(String fileName, boolean openOnCreation) {
		this(fileName, openOnCreation, 'n');

	}

	public LabsFileWriter(String fileName, char openAction) {
		this(fileName, false, openAction);

	}

	public LabsFileWriter(String fileName, boolean openOnCreation,
			char openAction) {
		super(fileName, false);
		this.openAction = openAction;
		if(openOnCreation) {
			open();
		}
	}

	public void open() {
		try {
			File temp;
			switch (openAction) {
			case 'n':
				temp = createNewFile();
				break;
			case 'a':
				temp = createNewFile(false);
				break;
			default:
				printError("Open writer failed, no suitable action defined");
				return;
			}
			writer = new BufferedWriter(new FileWriter(temp));
			setClosable(writer);
			setOpened(true);
		} catch (Exception ex) {
			printError("Couldn't open file: %s", getFileName());
			printException(ex);
		}
	}

	private File createNewFile() {
		return createNewFile(true);
	}

	private File createNewFile(boolean override) {
		File file = new File(getFileName());
		try {
			if (override || !file.exists()) {
				file.createNewFile();
			}
		} catch (Exception ex) {
			printError("Couldn't create New file: %s, override: %s",
					getFileName(), override);
			printException(ex);
		}
		return file;
	}

	public void flush() {
		if (!isOpened()) {
			printInfo("writer is not open to flush");
			return;
		}
		try {
			writer.flush();
		} catch (Exception ex) {
			printError("Couldn't Flush File Name: %s", getFileName());
			printException(ex);
		}

	}

	public void write(String str) {
		write(str, false);
	}

	private void write(String str, boolean newLine) {
		if (!isOpened()) {
			// printInfo("writer is not open to write");
			return;
		}
		try {
			switch (openAction) {
			case 'n':
				writer.write(str);
				break;
			case 'a':
				writer.append(str);
				break;
			default:
				break;
			}
			if (newLine) {
				writer.newLine();
			}
		} catch (Exception ex) {
			printError("Couldn't Write [File Name: %s, Content: %s]",
					getFileName(), str + (newLine ? "\n" : ""));
			printException(ex);
		}
	}

	public void writeLine(String line) {
		write(line, true);
	}

	public void writeLines(String[] lines, boolean flushEachLine) {
		for (String line : lines) {
			writeLine(line);
			if (flushEachLine) {
				flush();
			}
		}
		if (!flushEachLine) {
			flush();
		}
	}

	public void writeLines(String[] lines) {
		writeLines(lines, false);
	}
	
	public BufferedWriter getStreamWriter() {
		// TODO Auto-generated method stub
		return writer;
	}
}
